﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;

namespace Reap.Common.Runtime {
	/// <summary>
	/// MVC下面查找Bin所有程序集
	/// </summary>
	public class WebAppTypeFinder : AppDomainTypeFinder {
		#region Fields

		private bool _ensureBinFolderAssembliesLoaded = true;
		private bool _binFolderAssembliesLoaded = false;

		#endregion

		#region Ctor

		public WebAppTypeFinder() {
			this._ensureBinFolderAssembliesLoaded = true;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets wether assemblies in the bin folder of the web application should be specificly checked for beeing loaded on application load. This is need in situations where plugins need to be loaded in the AppDomain after the application been reloaded.
		/// </summary>
		public bool EnsureBinFolderAssembliesLoaded {
			get { return _ensureBinFolderAssembliesLoaded; }
			set { _ensureBinFolderAssembliesLoaded = value; }
		}

		#endregion

		#region Methods

		/// <summary>
		/// Gets a physical disk path of \Bin directory
		/// </summary>
		/// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>
		public virtual string GetBinDirectory() {
			if (HostingEnvironment.IsHosted) {
				//hosted
				return HttpRuntime.BinDirectory;
			} else {
				//not hosted. For example, run either in unit tests
				return AppDomain.CurrentDomain.BaseDirectory;
			}
		}


		public override IList<Assembly> GetAssemblies() {
			if (this.EnsureBinFolderAssembliesLoaded && !_binFolderAssembliesLoaded) {
				_binFolderAssembliesLoaded = true;
				string binPath = GetBinDirectory();
				//binPath = _webHelper.MapPath("~/bin");
				LoadMatchingAssemblies(binPath);
			}

			return base.GetAssemblies();
		}
		#endregion
	}
}
